Examples of decorators

Tags on web page

def makebold(fn):
    def wrapped():
        return "<b>" + fn() + "</b>"
    return wrapped

def makeitalic(fn):
    def wrapped():
        return "<i>" + fn() + "</i>"
    return wrapped

@makebold
@makeitalic
def hello():
    return "hello world"

print(hello())               # <b><i>hello world</i></b>
def shout(word = "yes"):
    return word.capitalize() + "!"
print(shout())                          #   Yes!

scream = shout
print(scream())                         #   Yes!

del shout

try:
    print(shout())
except NameError:
    print("Name 'shout' is not defined")  # Name 'shout' is not defined

# BUT:
print(scream())                           # Yes!
def talk():

    def whisper(word = "yes"):
        return word.lower() + "...";

    print(whisper())

talk()                                      # yes...

# BUT:
try:
    print(whisper())
except NameError:
    print("name 'whisper' is not defined")  # name 'whisper' is not defined
def getTalk(type="shout"):

    def shout(word="yes"):
        return word.capitalize() + "!"

    def whisper(word="yes"):
        return word.lower() + "..."

    if type == "shout":
        # return the function's object
        return shout
    else:
        return whisper

talk = getTalk()
print(talk)                     # <function getTalk.<locals>.shout at 0x00000000029AC8C8>
print(talk())                   # Yes!
print(getTalk("whisper")())     # yes...

def doSomethingBefore(func):
    print("Doing something before...")
    print(func())

doSomethingBefore(scream)       # Doing something before...; Yes!

Decorator

def my_shiny_new_decorator(a_function_to_decorate):

    def the_wrapper_around_the_original_function():

        print("Code before...")

        a_function_to_decorate()

        print("Code after...")

    return the_wrapper_around_the_original_function

def a_stand_alone_function():
    print("A simple function")

a_stand_alone_function()               # A simple function

# with decorator
a_stand_alone_function_decorated =
    my_shiny_new_decorator(a_stand_alone_function)  # to simplify the clause
a_stand_alone_function_decorated()     # Code before...; A simple function; Code after...

@my_shiny_new_decorator
def another_stand_alone_function():
    print("Live me alone")

another_stand_alone_function()                      # Code before...; Live me alone; Code after...

Embedded decorators

def bread(func):
    def wrapper():
        print("</------\>")
        func()
        print("<\______/>")
    return wrapper

def ingredients(func):
    def wrapper():
        print("#tomato")
        func()
        print("~salad~")
    return wrapper

def sandwich(food="--bacon--"):
    print(food)

sandwich()                                  # --bacon--
sandwich = bread(ingredients(sandwich))
sandwich()                                  #   </------\> ; #tomato; --bacon--; ~salad~; <\______/>

# OR, with decorators
@bread
@ingredients
def sandwich(food="--beacon--"):
    print(food)

sandwich()                                  #   </------\> ; #tomato; --bacon--; ~salad~; <\______/>